package com.huaxin.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.device.dto.ResponseResult;
import com.huaxin.device.dto.request.DeviceAlarmNotificationCreateReqDTO;
import com.huaxin.device.dto.request.DeviceAlarmNotificationPageListReqDTO;
import com.huaxin.device.dto.response.GetDeviceAlarmNotificationsByElectricianIdRespDTO;
import com.huaxin.device.feignClients.SysFeignService;
import com.huaxin.device.mapper.DeviceAlarmNotificationMapper;
import com.huaxin.device.mapping.DeviceAlarmNotificationMapping;
import com.huaxin.device.models.DeviceAlarmNotification;
import com.huaxin.device.service.DeviceAlarmNotificationService;
import com.huaxin.feignclient.system.models.ElectricianScopeDTO;
import com.huaxin.feignclient.system.models.Organization;
import com.huaxin.feignclient.websocket.models.SendMessageRequest;
import com.huaxin.hxenum.enums.NotificationReadStatus;
import com.huaxin.hxenum.enums.NotificationSendStatus;
import com.huaxin.hxrabbitmq.service.MessageSender;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

import static org.springframework.util.StringUtils.hasText;

@Service
@RequiredArgsConstructor
public class DeviceAlarmNotificationServiceImpl extends ServiceImpl<DeviceAlarmNotificationMapper, DeviceAlarmNotification> implements DeviceAlarmNotificationService {
    private final ApplicationContext applicationContext;
    private final DeviceAlarmNotificationMapping mapping;
    private final MessageSender messageSender;
    private final SysFeignService sysFeignService;

    @Override
    public Boolean create(DeviceAlarmNotificationCreateReqDTO in) {
        if (in == null) {
            return false;
        }
        if (!hasText(in.getDeviceAlarmId())) {
            return false;
        }
        if (!hasText(in.getRecipientId())) {
            return false;
        }
        if (in.getNotificationType() == null) {
            return false;
        }
        if (!hasText(in.getContent())) {
            return false;
        }
        DeviceAlarmNotification entity = mapping.toEntity(in);
        boolean saved = this.save(entity);
        if (!saved) {
            return false;
        }

        // 调用websocket向指定家庭成员推送消息
        return this.sendNotification(entity);
    }

    private Boolean sendNotification(DeviceAlarmNotification entity) {
        // 发送消息，并根据结果更新状态
        try {
            SendMessageRequest request = new SendMessageRequest();
            request.setTo(entity.getRecipientId());
            request.setContent(entity.getContent());

            // 发送到 MQ（同步调用，可能抛异常）
            messageSender.send(request);

            // 发送成功：更新状态为 sent，设置发送时间
            DeviceAlarmNotification update = new DeviceAlarmNotification();
            update.setId(entity.getId());
            update.setSendStatus(NotificationSendStatus.SENT);
            update.setSendTime(LocalDateTime.now());

            return this.updateById(update);

        } catch (Exception e) {
            // 发送失败：更新状态为 failed
            DeviceAlarmNotification update = new DeviceAlarmNotification();
            update.setId(entity.getId());
            update.setSendStatus(NotificationSendStatus.FAILED);
            update.setSendTime(LocalDateTime.now()); // 失败也记录时间

            this.updateById(update);
            return false;
        }
    }

    @Override
    public void create(List<DeviceAlarmNotificationCreateReqDTO> in) {
        if (in == null || in.isEmpty()) {
            return;
        }
        List<DeviceAlarmNotification> entityList = mapping.toEntityList(in);
        boolean saved = this.saveBatch(entityList);
        if (!saved) {
            return;
        }

        // 调用websocket向指定家庭成员推送消息
        for (DeviceAlarmNotification entity : entityList) {
            this.sendNotification(entity);
        }
    }

    @Override
    public DeviceAlarmNotification getByNotificationId(String id) {
        if (!hasText(id)) {
            throw new IllegalArgumentException("设备报警通知ID不能为空");
        }
        return this.getById(id);
    }

    @Override
    public ResponseResult<IPage<DeviceAlarmNotification>> pageQuery(DeviceAlarmNotificationPageListReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "分页查询参数不能为空");
        }

        IPage<DeviceAlarmNotification> page = new Page<>(in.getPageNum(), in.getPageSize());
        LambdaQueryWrapper<DeviceAlarmNotification> wrapper = new LambdaQueryWrapper<>();

        // 按通知类型过滤
        if (hasText(in.getNotificationType())) {
            wrapper.eq(DeviceAlarmNotification::getNotificationType, in.getNotificationType());
        }

        // 按通知发送状态过滤
        if (hasText(in.getNotificationSendStatus())) {
            wrapper.eq(DeviceAlarmNotification::getSendStatus, in.getNotificationSendStatus());
        }

        // 按通知阅读状态过滤
        if (hasText(in.getNotificationReadStatus())) {
            wrapper.eq(DeviceAlarmNotification::getReadStatus, in.getNotificationReadStatus());
        }

        // 按接收者ID过滤
        if (hasText(in.getRecipientId())) {
            wrapper.eq(DeviceAlarmNotification::getRecipientId, in.getRecipientId());
        }

        // 按组织ID过滤
        if (hasText(in.getOrgId())) {
            wrapper.eq(DeviceAlarmNotification::getOrgId, in.getOrgId());
        }

        // 按家庭ID过滤
        if (hasText(in.getFamilyId())) {
            wrapper.eq(DeviceAlarmNotification::getFamilyId, in.getFamilyId());
        }

        // 按创建时间排序
        wrapper.orderByDesc(DeviceAlarmNotification::getCreatedAt);

        IPage<DeviceAlarmNotification> resultPage = this.page(page, wrapper);
        return ResponseResult.ok(resultPage);
    }

    @Override
    public Boolean updateSendStatus(String id, NotificationSendStatus sendStatus) {
        if (!hasText(id)) {
            return false;
        }
        DeviceAlarmNotification entity = this.getById(id);
        if (entity == null) {
            return false;
        }
        entity.setSendStatus(sendStatus);
        return this.updateById(entity);
    }

    @Override
    public ResponseResult<Boolean> read(String id) {
        if (!hasText(id)) {
            return ResponseResult.parameterError(null, "设备报警通知ID不能为空");
        }
        DeviceAlarmNotification entity = this.getById(id);
        if (entity == null) {
            return ResponseResult.notFound(null, "设备报警通知不存在");
        }
        entity.setReadStatus(NotificationReadStatus.READ);
        return ResponseResult.ok(this.updateById(entity));
    }

    //根据电工id获取所关联的所有企业的设备预警通知
    @Override
    public ResponseResult<List<GetDeviceAlarmNotificationsByElectricianIdRespDTO>> getDeviceAlarmNotificationsByElectricianId(String electricianId) {
        // 1. 获取电工管辖范围
        List<ElectricianScopeDTO> electricianScopeList = sysFeignService.electricianScopeList(electricianId);

        // 2. 安全处理：空值返回空列表（符合接口契约）
        if (electricianScopeList == null || electricianScopeList.isEmpty()) {
            return ResponseResult.ok(Collections.emptyList());
        }

        // 3. 提取所有 orgId
        Set<String> orgIds = new HashSet<>();
        Map<String, String> orgIdToNameMap = new HashMap<>(); // 用于后续填充 orgName

        for (ElectricianScopeDTO scope : electricianScopeList) {
            if (scope.getOrgList() != null) {
                for (Organization org : scope.getOrgList()) {
                    if (org.getId() != null) {
                        orgIds.add(org.getId());
                        orgIdToNameMap.put(org.getId(), org.getName());
                    }
                }
            }
        }

        // 4. 如果没有有效的 orgId，直接返回空
        if (orgIds.isEmpty()) {
            return ResponseResult.ok(Collections.emptyList());
        }

        // 5. 【关键优化】使用 IN 一次性查询所有 orgId 的报警通知
        List<DeviceAlarmNotification> notifications = this.list(
                new LambdaQueryWrapper<DeviceAlarmNotification>()
                        .in(DeviceAlarmNotification::getOrgId, orgIds)
        );

        // 6. 构建结果列表
        List<GetDeviceAlarmNotificationsByElectricianIdRespDTO> resultList = new ArrayList<>();
        for (DeviceAlarmNotification notification : notifications) {
            String orgId = notification.getOrgId();
            String orgName = orgIdToNameMap.get(orgId); // 可能为 null，但通常不会

            GetDeviceAlarmNotificationsByElectricianIdRespDTO dto = new GetDeviceAlarmNotificationsByElectricianIdRespDTO();
            dto.setOrgId(orgId);
            dto.setOrgName(orgName);
            dto.setContent(notification.getContent());
            dto.setCreatedAt(notification.getCreatedAt());
            resultList.add(dto);
        }

        return ResponseResult.ok(resultList);
    }

    //根据企业id查询设备报警通知数量
    @Override
    public ResponseResult<Long> queryDeviceAlarmNotificationCountByOrgId(String orgId) {
        LambdaQueryWrapper<DeviceAlarmNotification> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeviceAlarmNotification::getOrgId, orgId);
        return ResponseResult.ok(this.count(wrapper));
    }
}
